Daily trade alerts for XMR

Mark Ziemann https://mdz-analytics.com

2022-09-29

Source code

Intro

In the backtesting analysis, I have established several different profitable strategies for timing entry/exits. Visit the XMR page to see how these signals were identified.

  1. Simple moving average (SMA)

  2. Exponential moving average (EMA)

  3. SMA crosses

  4. EMA crosses

  5. Directional movement index (DMI)

  6. True strength index (TSI) BEST

  7. Stochastic oscillator (stoch)

  8. Double RSI

  9. Donchian channel

  10. Know sure thing (KST)

  11. Ensembl indicator

This script will examine the price action and these trade signals just before the daily close. If the signal is TRUE, it is bullish and if FALSE it is bearish. When there is a switch from bearish to bullish it is a buy signal and when it switches from bullish to bearish it is a sell signal. This HTML is updated just before the daily close each day, but push notifications for any trade signals are also sent by push bullet.

To receive these signals in real-time, subscribe to the following channels - it’s free for a limited time!

https://www.pushbullet.com/channel?tag=xmr_signal

If you need some help to design your own trading signals/strategies, I am happy to help for a fee. email me at mark.ziemann{αt}gmail.com for any enquiries/suggestions/feedback.

This report is distributed for FREE under the MIT licence, but if you find it useful, consider a small tip.

Monero Address

Reminder: this analysis is not financial advice.

suppressPackageStartupMessages({
  library("jsonlite")
  library("tidyverse")
  library("runner")
  library("quantmod")
  library("TTR")
  library("RPushbullet")
  library("kableExtra")
})

TESTING = FALSE

MYNOTE = NULL
mydate <- Sys.time()
attr(mydate, "tzone") <- "UTC"
mydate <- as.Date(mydate)

Get XMR parameters

params <- read.table("https://mdz-analytics.com/coins/XMR/XMR_dat.txt", header=TRUE)
params %>% kbl(caption="optimised backtested parameters") %>%  kable_styling("hover", full_width = F)
optimised backtested parameters
indicator parameter meanROI totalROI ntrades ndays xhodl
SMA 26 1.081940 89.80789 136 3050 0.9986643
EMA 19 1.063057 116.41114 177 3050 1.2944926
SMAcross 188,118 40.788815 2193.13683 7 3050 24.3876959
EMAcross 74,7 1.591188 747.85506 25 3050 8.3161532
DMI 66 2.049948 700.15611 23 3050 7.7857406
DC 28 1.408096 453.01425 28 3050 5.0375215
TSI 81,23,4 1.160863 1129.21810 87 3050 12.5569127
stoch 17,60,6 1.196081 995.63657 74 3050 11.0714852
RSI2 32,89 1.093143 469.80768 143 3050 5.2242645
KST 1.2,0.18,49 1.214472 3246.12909 74 3050 36.0969767
Ensemble EMAcross,TSI,stoch,RSI2,DC,KST,3 1.173126 2206.94324 86 3050 40.7347497

Get XMR price data

Obtaining XMR price data (daily) for the last 300 days and today’s price.

URL="https://web-api.coinmarketcap.com/v1/cryptocurrency/ohlcv/historical?symbol=XMR&convert=USD&interval=daily&count=300"
download.file(URL,destfile="xmrdat.txt")
xmrdat <- fromJSON("xmrdat.txt")
price <- xmrdat$data$quotes
price <- data.frame(  as.Date(price$time_close) , price$quote$USD$high, price$quote$USD$low, price$quote$USD$close)
colnames(price) <- c("date","high","low","close")

URL="https://web-api.coinmarketcap.com/v1/cryptocurrency/ohlcv/historical?symbol=XMR&convert=USD&interval=hourly&time_period=hourly&count=11"
download.file(URL,destfile="xmrdat.txt")
xmrdat <- fromJSON("xmrdat.txt")
price2 <- xmrdat$data$quotes
price2 <- data.frame( as.Date(price2$time_close) , price2$quote$USD$high, price2$quote$USD$low, price2$quote$USD$close,stringsAsFactors=FALSE)
colnames(price2) <- c("date","high","low","close")

high <- max(price2[,2])
low <-  min(price2[,3])
close <- price2[nrow(price2),4]

df <- data.frame(date=mydate,high=high,low=low,close=close,stringsAsFactors=FALSE)
price <- rbind(price,df)
tail(price) %>% kbl(row.names = FALSE) %>% kable_styling("hover", full_width = F)
date high low close
2022-09-24 143.9085 140.7304 141.7651
2022-09-25 144.5276 140.1472 141.1041
2022-09-26 146.1058 139.9758 145.7094
2022-09-27 152.8920 143.1812 144.6130
2022-09-28 147.9419 140.3032 147.2961
2022-09-29 149.1473 146.7070 147.5753
if ( TESTING == TRUE) {
  price[nrow(price),"Close"] <- price[nrow(price),"Close"] * 2
}

XMR SMA indicator

Now to determine whether XMR has crossed the SMA line.

price2 <- price

n <- as.numeric(params[params$indicator == "SMA",2])

price2$ma <- SMA(Cl(price2),n=n)
price2$signal <- price2$close > price2$ma
tail(price2) %>% kbl(row.names = FALSE) %>% kable_styling("hover", full_width = F)
date high low close ma signal
2022-09-24 143.9085 140.7304 141.7651 149.3779 FALSE
2022-09-25 144.5276 140.1472 141.1041 149.0860 FALSE
2022-09-26 146.1058 139.9758 145.7094 148.9583 FALSE
2022-09-27 152.8920 143.1812 144.6130 148.6020 FALSE
2022-09-28 147.9419 140.3032 147.2961 148.3655 FALSE
2022-09-29 149.1473 146.7070 147.5753 148.1050 FALSE
today_signal <- price2[nrow(price2),"signal"]
previous_signal <- price2[(nrow(price2)-1),"signal"]
if (today_signal != previous_signal ) {
  if ( (today_signal == TRUE ) & (previous_signal == FALSE ) ) {
    xmr_signal="BUY"
  }
  if ( (today_signal == FALSE ) & (previous_signal == TRUE ) ) {
    xmr_signal="SELL"
  }
} else {
xmr_signal <- "NONE"
}

if (today_signal==TRUE) {
  ens_SMA=TRUE
} else {
  ens_SMA=FALSE
}

message(paste("XMR SMA signal:",xmr_signal))
## XMR SMA signal: NONE
plot(price2$close~as.Date(price2$date),type="l",
  xlab="Date",ylab="price (USD)",main="XMR w SMA")
grid()
lines(price2$ma~ as.Date(price2$date) ,col="red")

if ( xmr_signal != "NONE") {
  MYNOTE <- paste("The XMR SMA signal is", xmr_signal,".")
}

XMR EMA indicator

Now to determine whether XMR has crossed the EMA line.

price2 <- price

n <- as.numeric(params[params$indicator == "EMA",2])

price2$ma <- EMA(Cl(price2),n=n)
price2$signal <- price2$close > price2$ma
tail(price2) %>% kbl(row.names = FALSE) %>%  kable_styling("hover", full_width = F)
date high low close ma signal
2022-09-24 143.9085 140.7304 141.7651 146.3076 FALSE
2022-09-25 144.5276 140.1472 141.1041 145.7873 FALSE
2022-09-26 146.1058 139.9758 145.7094 145.7795 FALSE
2022-09-27 152.8920 143.1812 144.6130 145.6629 FALSE
2022-09-28 147.9419 140.3032 147.2961 145.8262 TRUE
2022-09-29 149.1473 146.7070 147.5753 146.0011 TRUE
today_signal <- price2[nrow(price2),"signal"]
previous_signal <- price2[(nrow(price2)-1),"signal"]
if (today_signal != previous_signal ) {
  if ( (today_signal == TRUE ) & (previous_signal == FALSE ) ) {
    xmr_signal="BUY"
  }
  if ( (today_signal == FALSE ) & (previous_signal == TRUE ) ) {
    xmr_signal="SELL"
  }
} else {
  xmr_signal <- "NONE"
}

if (today_signal==TRUE) {
  ens_EMA=TRUE
} else {
  ens_EMA=FALSE
}

message(paste("XMR EMA signal:",xmr_signal))
## XMR EMA signal: NONE
plot(price2$close~as.Date(price2$date),type="l",
  xlab="Date",ylab="price (USD)",main="XMR EMA")
grid()
lines(price2$ma~ as.Date(price2$date) ,col="red")

if ( xmr_signal != "NONE") {
  MYNOTE <- paste("The XMR EMA signal is", xmr_signal,".")
}

XMR SMA cross indicator

The SMA cross is a reasonably good strategy.

price2 <- price

n <- as.numeric(unlist(strsplit(params[params$indicator == "SMAcross",2],",")))
n1 <- n[1]
n2 <- n[2]

price2$ma1 <- SMA(Cl(price2),n=n1)
price2$ma2 <- SMA(Cl(price2),n=n2)

price2$signal <- price2$ma2 > price2$ma1
tail(price2) %>% kbl(row.names = FALSE) %>% kable_styling("hover", full_width = F)
date high low close ma1 ma2 signal
2022-09-24 143.9085 140.7304 141.7651 171.0662 148.3105 FALSE
2022-09-25 144.5276 140.1472 141.1041 170.7963 147.7758 FALSE
2022-09-26 146.1058 139.9758 145.7094 170.5402 147.3280 FALSE
2022-09-27 152.8920 143.1812 144.6130 170.2595 146.8703 FALSE
2022-09-28 147.9419 140.3032 147.2961 169.9583 146.4119 FALSE
2022-09-29 149.1473 146.7070 147.5753 169.6805 146.0186 FALSE
today_signal <- price2[nrow(price2),"signal"]
previous_signal <- price2[(nrow(price2)-1),"signal"]
if (today_signal != previous_signal ) {
  if ( (today_signal == TRUE ) & (previous_signal == FALSE ) ) {
    xmr_signal="BUY"
  }
  if ( (today_signal == FALSE ) & (previous_signal == TRUE ) ) {
    xmr_signal="SELL"
  }
} else {
xmr_signal <- "NONE"
}

if (today_signal==TRUE) {
  ens_SMAcross=TRUE
} else {
  ens_SMAcross=FALSE
}

message(paste("XMR SMA cross signal:",xmr_signal))
## XMR SMA cross signal: NONE
plot(price2$close~as.Date(price2$date),type="l",
  xlab="Date",ylab="price (USD)",main="XMR w SMA cross")
grid()
lines(price2$ma1~ as.Date(price2$date) ,col="red")
lines(price2$ma2~ as.Date(price2$date) ,col="blue")

if ( xmr_signal != "NONE") {
  MYNOTE <- paste(MYNOTE, "The XMR SMA cross signal is", xmr_signal,".")
}

XMR EMA cross indicator

The EMA cross is a moderately profitable strategy.

price2 <- price

n <- as.numeric(unlist(strsplit(params[params$indicator == "EMAcross",2],",")))
n1 <- n[1]
n2 <- n[2]

price2$ma1 <- EMA(Cl(price2),n=n1)
price2$ma2 <- EMA(Cl(price2),n=n2)

price2$signal <- price2$ma2 > price2$ma1
tail(price2) %>% kbl(row.names = FALSE) %>%  kable_styling("hover", full_width = F)
date high low close ma1 ma2 signal
2022-09-24 143.9085 140.7304 141.7651 151.4089 142.4285 FALSE
2022-09-25 144.5276 140.1472 141.1041 151.1341 142.0974 FALSE
2022-09-26 146.1058 139.9758 145.7094 150.9894 143.0004 FALSE
2022-09-27 152.8920 143.1812 144.6130 150.8194 143.4035 FALSE
2022-09-28 147.9419 140.3032 147.2961 150.7254 144.3767 FALSE
2022-09-29 149.1473 146.7070 147.5753 150.6414 145.1763 FALSE
today_signal <- price2[nrow(price2),"signal"]
previous_signal <- price2[(nrow(price2)-1),"signal"]
if (today_signal != previous_signal ) {
  if ( (today_signal == TRUE ) & (previous_signal == FALSE ) ) {
    xmr_signal="BUY"
  }
  if ( (today_signal == FALSE ) & (previous_signal == TRUE ) ) {
    xmr_signal="SELL"
  }
} else {
  xmr_signal <- "NONE"
}

if (today_signal==TRUE) {
  ens_EMAcross=TRUE
} else {
  ens_EMAcross=FALSE
}

message(paste("XMR EMA cross signal is",xmr_signal))
## XMR EMA cross signal is NONE
plot(price2$close~as.Date(price2$date),type="l",
  xlab="Date",ylab="price (USD)",main="XMR EMA cross")
grid()
lines(price2$ma1~ as.Date(price2$date) ,col="red")
lines(price2$ma2~ as.Date(price2$date) ,col="blue")

if ( xmr_signal != "NONE") {
  MYNOTE <- paste(MYNOTE, "The XMR EMA cross signal is", xmr_signal,".")
}

XMR DMI indicator

Directional movement indicator is a good approach to identify trend changes.

n <- as.numeric(params[params$indicator == "DMI",2])

dmi.adx <- ADX(price[,c("high","low","close")],n=n)
price2 <- cbind(price,dmi.adx)
price2$signal <- dmi.adx[,1] > dmi.adx[,2]
tail(price2) %>% kbl(row.names = FALSE) %>% kable_styling("hover", full_width = F)
date high low close DIp DIn DX ADX signal
2022-09-24 143.9085 140.7304 141.7651 17.66315 22.33587 11.682092 8.326711 FALSE
2022-09-25 144.5276 140.1472 141.1041 17.63814 22.17759 11.401161 8.373294 FALSE
2022-09-26 146.1058 139.9758 145.7094 17.71896 21.95651 10.680525 8.408252 FALSE
2022-09-27 152.8920 143.1812 144.6130 18.54223 21.60998 7.640315 8.396616 FALSE
2022-09-28 147.9419 140.3032 147.2961 18.31140 21.80999 8.720005 8.401516 FALSE
2022-09-29 149.1473 146.7070 147.5753 18.43643 21.72227 8.182149 8.398192 FALSE
today_signal <- price2[nrow(price2),"signal"]
previous_signal <- price2[(nrow(price2)-1),"signal"]
if (today_signal != previous_signal ) {
  if ( (today_signal == TRUE ) & (previous_signal == FALSE ) ) {
    xmr_signal="BUY"
  }
  if ( (today_signal == FALSE ) & (previous_signal == TRUE ) ) {
    xmr_signal="SELL"
  }
} else {
  xmr_signal <- "NONE"
}

if (today_signal==TRUE) {
  ens_DMI=TRUE
} else {
  ens_DMI=FALSE
}

message(paste("XMR DMI signal:",xmr_signal))
## XMR DMI signal: NONE
price2 <- as.data.frame(price2)
par(mfrow=c(2,1))
plot(price2$close~as.Date(price2$date),type="l",
  xlab="Date",ylab="price (USD)",main="XMR USD price")
grid()
plot(price2$DIp~as.Date(price2$date),type="l", col="blue",
  xlab="Date",ylab="price (USD)",main="XMR DMI")
grid()
lines(price2$DIn ~ as.Date(price2$date) ,col="red")

if ( xmr_signal != "NONE") {
  MYNOTE <- paste(MYNOTE,"XMR DMI signal is", xmr_signal,".")
}

XMR TSI indicator

True Strength Indicator is one of the more profitable approaches. Its success lies in how it changes rapidly when momentum shifts. For most coins, this indicator performs “best” in backtesting analysis, which means it should carry relatively more weight than other indicators.

n <- as.numeric(unlist(strsplit(params[params$indicator == "TSI",2],",")))
n1 <- n[1]
n2 <- n[2]
ns <- n[3]

TSI <- function(x, n.first = 25, n.second = 13, n.signal = 7) {
  #True Strength Indicator
  #https://school.stockcharts.com/doku.php?id=technical_indicators:true_strength_index
  x <- try.xts(x, error = as.matrix)
  pc <- x - lag.xts(x, na.pad = T) #force lag.xts to get na padding
  dspc <- EMA(EMA(pc, n = n.first), n = n.second)
  dsapc <- EMA(EMA(abs(pc), n = n.first), n = n.second)

  tsi <- 100 * (dspc/dsapc)
  signal <- EMA(tsi, n = n.signal)
  r <- cbind(tsi, signal)
  r <- reclass(r, x)
  if (!is.null(dim(r))) colnames(r) <- c("tsi", "signal")
  return(r)
}

tsi <- TSI(price$close , n.first = n1, n.second = n2, n.signal = ns )
colnames(tsi) <- c("tsi","sig")

price2 <- cbind(price,tsi)
price2$signal <- tsi[,1] > tsi[,2]
tail(price2) %>% kbl(row.names = FALSE) %>% kable_styling("hover", full_width = F)
date high low close tsi sig signal
2022-09-24 143.9085 140.7304 141.7651 -3.392380 -3.052215 FALSE
2022-09-25 144.5276 140.1472 141.1041 -3.579238 -3.263025 FALSE
2022-09-26 146.1058 139.9758 145.7094 -3.546762 -3.376520 FALSE
2022-09-27 152.8920 143.1812 144.6130 -3.562248 -3.450811 FALSE
2022-09-28 147.9419 140.3032 147.2961 -3.457844 -3.453624 FALSE
2022-09-29 149.1473 146.7070 147.5753 -3.350880 -3.412526 TRUE
today_signal <- price2[nrow(price2),"signal"]
previous_signal <- price2[(nrow(price2)-1),"signal"]
if (today_signal != previous_signal ) {
  if ( (today_signal == TRUE ) & (previous_signal == FALSE ) ) {
    xmr_signal="BUY"
  }
  if ( (today_signal == FALSE ) & (previous_signal == TRUE ) ) {
    xmr_signal="SELL"
  }
} else {
  xmr_signal <- "NONE"
}

if (today_signal==TRUE) {
  ens_TSI=TRUE
} else {
  ens_TSI=FALSE
}

message(paste("XMR TSI signal:",xmr_signal))
## XMR TSI signal: BUY
par(mfrow=c(2,1))
plot(price2$close ~ as.Date(price2$date),type="l",log="y",
  xlab="Date",ylab="price (USD)",main="USD price")
grid()

plot(tsi[,1] ~ as.Date(price2$date),type="l",col="blue",
  xlab="Date",ylab="TSI",main="TSI")
lines(as.Date(price2$date), tsi[,2]  , col="red"  )
grid()

par(mfrow=c(1,1))
if ( xmr_signal != "NONE") {
  MYNOTE <- paste(MYNOTE,"XMR TSI signal is", xmr_signal,".")
}

XMR stochastic oscillator indicator

Similar to the TSI, the stoch can pinpoint early changes in momentum, however it may give many false positives.

n <- as.numeric(unlist(strsplit(params[params$indicator == "stoch",2],",")))
n1 <- n[1]
n2 <- n[2]
n3 <- n[3]

sto <- stoch(HLC(price), nFastK=n1 , nFastD=n2 , nSlowD=n2 , bounded = TRUE, smooth=n3)

price2 <- cbind(price,sto)
price2$signal <- price2$fastK > price2$fastD

tail(price2) %>% kbl(row.names = FALSE) %>% kable_styling("hover", full_width = F)
date high low close fastK fastD slowD signal
2022-09-24 143.9085 140.7304 141.7651 0.2047479 0.5318638 0.6157778 FALSE
2022-09-25 144.5276 140.1472 141.1041 0.2143011 0.5207693 0.6153552 FALSE
2022-09-26 146.1058 139.9758 145.7094 0.2384226 0.5099432 0.6147129 FALSE
2022-09-27 152.8920 143.1812 144.6130 0.2894465 0.4998074 0.6138688 FALSE
2022-09-28 147.9419 140.3032 147.2961 0.3061969 0.4904259 0.6128416 FALSE
2022-09-29 149.1473 146.7070 147.5753 0.3392374 0.4817052 0.6116438 FALSE
today_signal <- price2[nrow(price2),"signal"]
previous_signal <- price2[(nrow(price2)-1),"signal"]
if (today_signal != previous_signal ) {
  if ( (today_signal == TRUE ) & (previous_signal == FALSE ) ) {
    xmr_signal="BUY"
  }
  if ( (today_signal == FALSE ) & (previous_signal == TRUE ) ) {
    xmr_signal="SELL"
  }
} else {
  xmr_signal <- "NONE"
}

if (today_signal==TRUE) {
  ens_stoch=TRUE
} else {
  ens_stoch=FALSE
}

message(paste("XMR stoch signal:",xmr_signal))
## XMR stoch signal: NONE
par(mfrow=c(2,1))
plot(price2$close ~ as.Date(price2$date),type="l",log="y",
  xlab="Date",ylab="price (USD)",main="USD price")
grid()

plot(price2$fastK ~ as.Date(price2$date),type="l",col="blue",
  xlab="Date",ylab="index",main="stochastic oscillator")
lines(as.Date(price2$date), price2$fastD  , col="red"  )
grid()

par(mfrow=c(1,1))
if ( xmr_signal != "NONE") {
  MYNOTE <- paste(MYNOTE,"XMR Stoch signal is", xmr_signal,".")
}

XMR double RSI indicator

Double RSI is simply two RSI lines.

n <- as.numeric(unlist(strsplit(params[params$indicator == "RSI2",2],",")))
n1 <- n[1]
n2 <- n[2]

rsi1 <- RSI(price$close,n=n1,maType=EMA)
rsi2 <- RSI(price$close,n=n2,maType=EMA)

price2 <- cbind(price,rsi1,rsi2)
price2$signal <- price2$rsi1 > price2$rsi2

tail(price2) %>% kbl(row.names = FALSE) %>% kable_styling("hover", full_width = F)
date high low close rsi1 rsi2 signal
2022-09-24 143.9085 140.7304 141.7651 44.97797 47.38342 FALSE
2022-09-25 144.5276 140.1472 141.1041 44.53856 47.23518 FALSE
2022-09-26 146.1058 139.9758 145.7094 48.28575 48.38581 FALSE
2022-09-27 152.8920 143.1812 144.6130 47.47291 48.13027 FALSE
2022-09-28 147.9419 140.3032 147.2961 49.67966 48.80695 TRUE
2022-09-29 149.1473 146.7070 147.5753 49.91279 48.87794 TRUE
today_signal <- price2[nrow(price2),"signal"]
previous_signal <- price2[(nrow(price2)-1),"signal"]
if (today_signal != previous_signal ) {
  if ( (today_signal == TRUE ) & (previous_signal == FALSE ) ) {
    xmr_signal="BUY"
  }
  if ( (today_signal == FALSE ) & (previous_signal == TRUE ) ) {
    xmr_signal="SELL"
  }
} else {
  xmr_signal <- "NONE"
}

if (today_signal==TRUE) {
  ens_RSI2=TRUE
} else {
  ens_RSI2=FALSE
}

message(paste("XMR RSI signal:",xmr_signal))
## XMR RSI signal: NONE
par(mfrow=c(2,1))
plot(price2$close ~ as.Date(price2$date),type="l",log="y",
  xlab="Date",ylab="price (USD)",main="USD price")
grid()

plot(price2$rsi1 ~ as.Date(price2$date),type="l",col="blue",
  xlab="Date",ylab="index",main="double RSI")
lines(as.Date(price2$date), price2$rsi2  , col="red"  )
grid()

par(mfrow=c(2,1))
plot(price2$close ~ as.Date(price2$date),type="l",log="y",
  xlab="Date",ylab="price (USD)",main="USD price")
grid()

plot(price2$rsi1/price2$rsi2 ~ as.Date(price2$date),type="l",
  xlab="Date",ylab="RSI ratio",main="double RSI")
grid()
abline(h=1,lty=2,lwd=2)

par(mfrow=c(1,1))
if ( xmr_signal != "NONE") {
  MYNOTE <- paste(MYNOTE,"XMR RSI2 signal is", xmr_signal,".")
}

XMR Donchian channel indicator

n <- as.numeric(params[params$indicator == "DC",2])

price2 <- price[1:nrow(price)-1,]
dc <- DonchianChannel(price2$close,n=n)

price2$higher <- c(NA,sapply(2:nrow(dc),function(i) {
  dc[i,"high"] > dc[(i-1),"high"]
} ))
price2$lower <- c(NA,sapply(2:nrow(dc),function(i) {
  dc[i,"low"] < dc[(i-1),"low"]
} ))
price2 <- price2[price2$higher != price2$lower,]
# show changing rows only
price2 <- price2[c(NA,unlist(lapply(2:nrow(price2) , function(i) {
  price2$higher[i] != price2$higher[i-1]
}))),]
price2 <- price2[!is.na(price2$higher),]

previous_signal <- price2[nrow(price2),"higher"]

price2 <- price
dc <- DonchianChannel(price2$close,n=n)
colnames(dc) <- c("dchigh","dcmid","dclow")
price2 <- cbind(price2,dc)

tail(price2) %>% kbl(row.names = FALSE) %>%  kable_styling("hover", full_width = F)
date high low close dchigh dcmid dclow
2022-09-24 143.9085 140.7304 141.7651 163.9119 149.7593 135.6067
2022-09-25 144.5276 140.1472 141.1041 163.9119 149.7593 135.6067
2022-09-26 146.1058 139.9758 145.7094 163.9119 149.7593 135.6067
2022-09-27 152.8920 143.1812 144.6130 163.9119 149.7593 135.6067
2022-09-28 147.9419 140.3032 147.2961 163.9119 149.7593 135.6067
2022-09-29 149.1473 146.7070 147.5753 163.9119 149.7593 135.6067
xmr_signal="NONE"

# if we in negative territory, check whether time to buy
if ( previous_signal == FALSE ) {
  if ( price2[nrow(price2),"dchigh"] > price2[nrow(price2)-1,"dchigh"] ) {
    xmr_signal="BUY"
  }
}

# if we in positive territory, check whether time to sell
if ( previous_signal == TRUE ) {
  if ( price2[nrow(price2),"dclow"] < price2[nrow(price2)-1,"dclow"] ) {
    xmr_signal="SELL"
  }
}

if ( xmr_signal=="NONE" ) {
  today_signal=previous_signal
} else {
  if (xmr_signal=="BUY") { today_signal = TRUE }
  if (xmr_signal=="SELL") { today_signal = FALSE }
}

if (today_signal==TRUE) {
  ens_DC=TRUE
} else {
  ens_DC=FALSE
}

message(paste("XMR DC signal:",xmr_signal))
## XMR DC signal: NONE
plot(price2$close ~ as.Date(price2$date),type="l",log="y",
  xlab="Date",ylab="price (USD)",main="USD price",lwd=2)
grid()

lines(price2$dclow~ as.Date(price2$date),lwd=1.5,col="red")
lines(price2$dchigh~ as.Date(price2$date),lwd=1.5,col="limegreen")

price2 <- tail(price2,100)

plot(price2$close ~ as.Date(price2$date),type="l",log="y",
  xlab="Date",ylab="price (USD)",main="USD price",lwd=2)
grid()

lines(price2$dclow~ as.Date(price2$date),lwd=1.5,col="red")
lines(price2$dcmid~ as.Date(price2$date),lwd=1.5,col="gray")
lines(price2$dchigh~ as.Date(price2$date),lwd=1.5,col="limegreen")

if ( xmr_signal != "NONE") {
  MYNOTE <- paste(MYNOTE,"XMR Donchian channel signal is", xmr_signal,".")
}

XMR KST indicator

Another high-performing indicator across different price series data.

price2 <- price

n <- as.numeric(unlist(strsplit(params[params$indicator == "KST",2],",")))
nScale <- n[1]
nrocScale <- n[2]
nSigs <- n[3]

kst <- KST(price2$close,n=nScale * c(10, 10, 10, 15) ,
  nROC=nrocScale * c(10, 15, 20, 30),
  nSig=nSigs)

price2 <- cbind(price2,kst)
price2$KST <- as.numeric(kst[,1]>kst[,2])

tail(price2) %>% kbl(row.names = FALSE) %>%  kable_styling("hover", full_width = F)
date high low close kst signal KST
2022-09-24 143.9085 140.7304 141.7651 -23.477129 -3.511337 0
2022-09-25 144.5276 140.1472 141.1041 -19.273361 -4.365961 0
2022-09-26 146.1058 139.9758 145.7094 -13.152069 -5.037067 0
2022-09-27 152.8920 143.1812 144.6130 -9.681649 -5.472140 0
2022-09-28 147.9419 140.3032 147.2961 -8.171095 -5.892443 0
2022-09-29 149.1473 146.7070 147.5753 -8.423658 -6.314720 0
today_signal <- price2[nrow(price2),"KST"]
previous_signal <- price2[(nrow(price2)-1),"KST"]
if (today_signal != previous_signal ) {
  if ( (today_signal == TRUE ) & (previous_signal == FALSE ) ) {
    signal="BUY"
  }
  if ( (today_signal == FALSE ) & (previous_signal == TRUE ) ) {
    signal="SELL"
  }
} else {
  signal <- "NONE"
}

if (today_signal==TRUE) {
  ens_DMI=TRUE
} else {
  ens_DMI=FALSE
}

message(paste("XMR KST signal:",xmr_signal))
## XMR KST signal: NONE
par(mfrow=c(2,1))
plot(price2$close ~ as.Date(price2$date),type="l",log="y",
  xlab="Date",ylab="price (USD)",main="USD price")
grid()

plot(kst[,1] ~ as.Date(price2$date),type="l",col="blue",
  xlab="Date",ylab="KST",main="KST")
lines(as.Date(price2$date), kst[,2]  , col="red"  )
grid()

par(mfrow=c(1,1))
if ( xmr_signal != "NONE") {
  MYNOTE <- paste(MYNOTE,"XMR KST signal is", xmr_signal,".")
}

XMR Ensemble indicator

This is a combination of a number of indicators.

ens <- params[params$indicator=="Ensemble","parameter"]
myrev <- intToUtf8(rev(utf8ToInt(ens)))
myrev <- unlist(strsplit(myrev,","))
# get thresh
n <- as.numeric(myrev[1])
myrev <- myrev[2:length(myrev)]
# get combination
combo <- sapply(myrev,function(s) { intToUtf8(rev(utf8ToInt(s))) })

message(paste("The combination is",paste(combo,collapse=" ")))
## The combination is KST DC RSI2 stoch TSI EMAcross
message(paste("The buy threshold is",n))
## The buy threshold is 3
indicators <- c("SMA"=ens_SMA,
  "EMA"=ens_EMA,
  "SMAcross"=ens_SMAcross,
  "EMAcross"=ens_EMAcross,
  "DMI"=ens_DMI,
  "TSI"=ens_TSI,
  "stoch"=ens_stoch,
  "RSI2"=ens_RSI2,
  "DC"=ens_DC)

indicators <- indicators[names(indicators) %in% combo]
message("State of the indicators:")
## State of the indicators:
indicators
## EMAcross      TSI    stoch     RSI2       DC 
##    FALSE     TRUE    FALSE     TRUE    FALSE
today_count <- sum(indicators)
message(paste("today_count_XMR",today_count,sep="="))
## today_count_XMR=2
today_signal <- today_count>=n

prev_html <- readLines("https://mdz-analytics.com/coins/XMR/alerts_XMR.html")
prev_signal <- length(grep("XMR ensemble indicator is BULLISH",prev_html))>2

xmr_signal <- "NONE"

if ( today_signal != prev_signal ) {
  if ( today_signal == TRUE ) {
    xmr_signal="BUY"
  } else {
    xmr_signal="SELL"
  }
}

if (today_signal==TRUE) {
  message("XMR ensemble indicator is BULLISH")
} else {
  message("XMR ensemble indicator is BEARISH")
}
## XMR ensemble indicator is BEARISH
message(paste("XMR ENS signal:",xmr_signal))
## XMR ENS signal: NONE
if ( xmr_signal != "NONE") {
  MYNOTE <- paste(MYNOTE,"XMR Ensemble indicator is", xmr_signal,".")
}

Send a push notification.

MYNOTE
## [1] " XMR TSI signal is BUY ."
if ( !is.null(MYNOTE) ) {
  MYNOTE <- paste(MYNOTE, ". Visit https://mdz-analytics.com/coins/XMR/alerts_XMR.html for the details")
  MYNOTE
  pbPost("note", "Crypto Alert", MYNOTE ,channel="xmr_signal")
}

Session information

For reproducibility


Click HERE to show session info

sessionInfo()
## R version 4.1.2 (2021-11-01)
## Platform: aarch64-unknown-linux-gnu (64-bit)
## Running under: Ubuntu 22.04.1 LTS
## 
## Matrix products: default
## BLAS:   /usr/lib/aarch64-linux-gnu/blas/libblas.so.3.10.0
## LAPACK: /usr/lib/aarch64-linux-gnu/lapack/liblapack.so.3.10.0
## 
## locale:
##  [1] LC_CTYPE=en_AU.UTF-8       LC_NUMERIC=C              
##  [3] LC_TIME=en_AU.UTF-8        LC_COLLATE=en_AU.UTF-8    
##  [5] LC_MONETARY=en_AU.UTF-8    LC_MESSAGES=en_AU.UTF-8   
##  [7] LC_PAPER=en_AU.UTF-8       LC_NAME=C                 
##  [9] LC_ADDRESS=C               LC_TELEPHONE=C            
## [11] LC_MEASUREMENT=en_AU.UTF-8 LC_IDENTIFICATION=C       
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
##  [1] kableExtra_1.3.4  RPushbullet_0.3.4 quantmod_0.4.20   TTR_0.24.3       
##  [5] xts_0.12.1        zoo_1.8-10        runner_0.4.1      forcats_0.5.1    
##  [9] stringr_1.4.0     dplyr_1.0.9       purrr_0.3.4       readr_2.1.2      
## [13] tidyr_1.2.0       tibble_3.1.8      ggplot2_3.3.6     tidyverse_1.3.2  
## [17] jsonlite_1.8.0   
## 
## loaded via a namespace (and not attached):
##  [1] httr_1.4.4          sass_0.4.2          viridisLite_0.4.0  
##  [4] modelr_0.1.8        bslib_0.4.0         assertthat_0.2.1   
##  [7] highr_0.9           googlesheets4_1.0.1 cellranger_1.1.0   
## [10] yaml_2.3.5          pillar_1.8.0        backports_1.4.1    
## [13] lattice_0.20-45     glue_1.6.2          digest_0.6.29      
## [16] rvest_1.0.2         colorspace_2.0-3    htmltools_0.5.3    
## [19] pkgconfig_2.0.3     broom_1.0.0         haven_2.5.0        
## [22] bookdown_0.28       scales_1.2.0        webshot_0.5.3      
## [25] svglite_2.1.0       tzdb_0.3.0          googledrive_2.0.0  
## [28] generics_0.1.3      ellipsis_0.3.2      cachem_1.0.6       
## [31] withr_2.5.0         cli_3.3.0           magrittr_2.0.3     
## [34] crayon_1.5.1        readxl_1.4.1        evaluate_0.16      
## [37] fs_1.5.2            fansi_1.0.3         xml2_1.3.3         
## [40] tools_4.1.2         hms_1.1.1           gargle_1.2.0       
## [43] lifecycle_1.0.1     munsell_0.5.0       reprex_2.0.2       
## [46] compiler_4.1.2      jquerylib_0.1.4     systemfonts_1.0.4  
## [49] rlang_1.0.4         grid_4.1.2          rstudioapi_0.13    
## [52] rmarkdown_2.15      gtable_0.3.0        DBI_1.1.3          
## [55] curl_4.3.2          R6_2.5.1            lubridate_1.8.0    
## [58] knitr_1.39          fastmap_1.1.0       utf8_1.2.2         
## [61] stringi_1.7.8       parallel_4.1.2      rmdformats_1.0.4   
## [64] Rcpp_1.0.9          vctrs_0.4.1         dbplyr_2.2.1       
## [67] tidyselect_1.1.2    xfun_0.32